#include <webx/menu.h>
#include <dbentity/T_XG_MENU.h>
#include <dbentity/T_XG_GROUP.h>

class EditMenu : public webx::ProcessBase
{
protected:
	int process();
};

HTTP_WEBAPP(EditMenu)

int EditMenu::process()
{
	param_string(id);
	param_string(url);
	param_string(flag);
	param_string(icon);
	param_string(title);
	param_string(folder);
	param_string(remark);
	param_string(enabled);
	param_string(grouplist);

	webx::CheckAlnumString(id, 0);
	webx::CheckFileName(title, 0);
	webx::CheckFileName(folder, 0);

	checkLogin();
	checkSystemRight();

	string sqlcmd;
	CT_XG_MENU tab;
	int res = XG_PARAMERR;
	sp<DBConnect> dbconn = webx::GetDBConnect();
	
	tab.init(dbconn);
	tab.id = id;

	if (flag == "A" || flag == "C" || flag == "R")
	{
		if (icon.empty())
		{
			if (flag == "C")
			{
				icon = "/res/img/menu/folder.png";
			}
			else
			{
				icon = "/res/img/menu/menu.png";
			}
		}
		
		if (flag == "R")
		{
			stdx::format(sqlcmd, "FOLDER='%s' AND (TITLE IS NULL OR TITLE='') AND ENABLED>1", folder.c_str());
			
			if (!tab.find(sqlcmd))
			{
				res = XG_SYSERR;
			}
			else if (tab.next())
			{
				res = tab.remove(sqlcmd);
			}
			else
			{
				res = XG_NOTFOUND;
			}
		}
		else
		{
			tab.url = url;
			tab.icon = icon;
			tab.title = title;
			tab.folder = folder;
			tab.remark = remark;
			tab.enabled = enabled;
			tab.statetime.update();

			for (int i = 0; i < 5; i++)
			{
				tab.id = DateTime::GetBizId();
				tab.position = (int)(time(NULL));

				if ((res = tab.insert()) >= 0) break;
			}

			if (res > 0)
			{
				json["icon"] = tab.icon.val();
				json["id"] = tab.id.val();
			}
		}
	}
	else if (flag == "D")
	{
		res = XG_NOTFOUND;

		if (id.empty()) return simpleResponse(XG_PARAMERR);

		if (!tab.find()) return simpleResponse(XG_SYSERR);
		
		if (tab.next() && tab.enabled.val() > 1)
		{
			if ((res = tab.remove()) < 0) return simpleResponse(res);

			string tag;
			string menulist;
			CT_XG_GROUP grptab;
			map<string, string> upmap;
			
			tag = "," + id + ",";

			grptab.init(dbconn);
			grptab.find("");

			while (grptab.next())
			{
				menulist = "," + grptab.menulist.val() + ",";
				menulist = stdx::replace(menulist, tag, ",");
				menulist = menulist.substr(1, menulist.length() - 2);

				if (menulist != grptab.menulist.val())
				{
					upmap[grptab.id.val()] = menulist;
				}
			}

			grptab.clear();

			for (auto& item : upmap)
			{
				grptab.id = item.first;
				grptab.menulist = item.second;

				if ((res == grptab.update()) < 0) return simpleResponse(XG_SYSERR);
			}
		}
	}
	else if (flag == "U")
	{
		res = XG_NOTFOUND;

		if (id.empty()) return simpleResponse(XG_PARAMERR);

		if (!tab.find()) return simpleResponse(XG_SYSERR);

		if (tab.next() && tab.enabled.val() > 1)
		{
			tab.statetime.update();
			
			if (url.length() > 0) tab.url = url;
			if (icon.length() > 0) tab.icon = icon;
			if (title.length() > 0) tab.title = title;
			if (folder.length() > 0) tab.folder = folder;
			if (remark.length() > 0) tab.remark = remark;
			if (enabled.length() > 0) tab.enabled = enabled;

			json["icon"] = tab.icon.val();

			if ((res = tab.update()) < 0) return simpleResponse(res);

			string tag;
			string menulist;
			CT_XG_GROUP grptab;
			map<string, string> upmap;
			
			tag = "," + id + ",";
			
			grptab.init(dbconn);
			
			for (JsonElement item : JsonElement(grouplist))
			{
				grptab.id = item["id"].asString();
				
				if (grptab.find() && grptab.next())
				{
					menulist = "," + grptab.menulist.val() + ",";
			
					if (item["checked"].asBoolean())
					{
						if (menulist.find(tag) == string::npos)
						{
							menulist += id + ",";
						}
					}
					else
					{
						menulist = stdx::replace(menulist, tag, ",");
					}
					
					menulist = stdx::trim(menulist, ", \r\n\t");
					
					if (menulist != grptab.menulist.val())
					{
						upmap[grptab.id.val()] = menulist;
					}
				}
			}

			grptab.clear();
			
			for (auto& item : upmap)
			{
				grptab.id = item.first;
				grptab.menulist = item.second;
			
				if ((res == grptab.update()) < 0) return simpleResponse(res);
			}
		}
	}
	else if (flag == "M")
	{
		res = XG_SYSERR;

		param_string(direct);

		while (true)
		{
			sp<RowData> row;
			vector<string> vec;
			sp<QueryResult> rs;
				
			stdx::format(sqlcmd, "SELECT MIN(ID),MAX(ID),COUNT(1) AS NUM FROM T_XG_MENU GROUP BY POSITION HAVING NUM>1");

			if (rs = dbconn->query(sqlcmd))
			{
				int position = time(NULL) - rand() % 100000000 - 1;

				while (row = rs->next())
				{
					stdx::format(sqlcmd, "UPDATE T_XG_MENU SET POSITION=%d WHERE ID='%s'", position, row->getString(0).c_str());
					vec.push_back(sqlcmd);

					stdx::format(sqlcmd, "UPDATE T_XG_MENU SET POSITION=%d WHERE ID='%s'", position - rand() % 1000000 - 1, row->getString(1).c_str());
					vec.push_back(sqlcmd);
				}
				
				for (string& sqlcmd : vec)
				{
					if (dbconn->execute(sqlcmd) < 0)
					{
						vec.clear();

						break;
					}
				}
			}

			if (vec.empty()) break;
		}

		if (id.length() > 0)
		{
			if (tab.find() && tab.next())
			{
				folder = tab.folder.val();

				int srcpos = tab.position.val();

				if (direct == "U")
				{
					stdx::format(sqlcmd, "FOLDER='%s' AND POSITION<%d AND LENGTH(TITLE)>0 ORDER BY POSITION DESC", folder.c_str(), srcpos);
				}
				else
				{
					stdx::format(sqlcmd, "FOLDER='%s' AND POSITION>%d AND LENGTH(TITLE)>0 ORDER BY POSITION ASC", folder.c_str(), srcpos);
				}

				if (tab.find(sqlcmd))
				{
					int destpos = srcpos;

					if (tab.next()) destpos = tab.position.val();

					if (srcpos == destpos)
					{
						stdx::format(sqlcmd, "UPDATE T_XG_MENU SET POSITION=POSITION%s WHERE ID='%s'", direct == "U" ? "-1" : "+1", id.c_str());

						res = dbconn->execute(sqlcmd);
					}
					else
					{
						stdx::format(sqlcmd, "UPDATE T_XG_MENU SET POSITION=%d WHERE FOLDER='%s' AND ID='%s' AND LENGTH(TITLE)>0 AND POSITION=%d", destpos, folder.c_str(), id.c_str(), srcpos);
						
						if ((res = dbconn->execute(sqlcmd)) < 0) return simpleResponse(res);

						stdx::format(sqlcmd, "UPDATE T_XG_MENU SET POSITION=%d WHERE FOLDER='%s' AND ID<>'%s' AND LENGTH(TITLE)>0 AND POSITION=%d", srcpos, folder.c_str(), id.c_str(), destpos);

						res = dbconn->execute(sqlcmd);
					}
				}
			}
		}
		else if (folder.length() > 0)
		{
			stdx::format(sqlcmd, "FOLDER='%s' AND (TITLE IS NULL OR TITLE='')", folder.c_str());

			if (tab.find(sqlcmd) && tab.next())
			{
				int srcpos = tab.position.val();

				if (direct == "U")
				{
					stdx::format(sqlcmd, "POSITION<%d AND (TITLE IS NULL OR TITLE='') ORDER BY POSITION DESC", srcpos);
				}
				else
				{
					stdx::format(sqlcmd, "POSITION>%d AND (TITLE IS NULL OR TITLE='') ORDER BY POSITION ASC", srcpos);
				}

				if (tab.find(sqlcmd))
				{
					int destpos = srcpos;

					if (tab.next()) destpos = tab.position.val();

					if (srcpos == destpos)
					{
						stdx::format(sqlcmd, "UPDATE T_XG_MENU SET POSITION=POSITION%s WHERE FOLDER='%s' AND (TITLE IS NULL OR TITLE='')", direct == "U" ? "-1" : "+1", folder.c_str());

						res = dbconn->execute(sqlcmd);
					}
					else
					{
						stdx::format(sqlcmd, "UPDATE T_XG_MENU SET POSITION=%d WHERE FOLDER='%s' AND (TITLE IS NULL OR TITLE='') AND POSITION=%d", destpos, folder.c_str(), srcpos);

						if ((res = dbconn->execute(sqlcmd)) >= 0)
						{
							stdx::format(sqlcmd, "UPDATE T_XG_MENU SET POSITION=%d WHERE FOLDER<>'%s' AND (TITLE IS NULL OR TITLE='') AND POSITION=%d", srcpos, folder.c_str(), destpos);

							res = dbconn->execute(sqlcmd);
						}
					}
				}
			}
		}
	}
	else
	{
		res = XG_PARAMERR;
	}

	if (res >= 0)
	{
		Process::SetObject("HTTP_GROUP_SET", NULL);
		Process::SetObject("HTTP_MENU_SET", NULL);
	}

	json["code"] = res;
	out << json;
	
	return XG_OK;
}